using System.Collections;
using UnityEngine;

[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer))]
public class Liquid : MonoBehaviour
{
	private MeshFilter meshFilter;

	private MeshRenderer meshRenderer;

	private WaveGenerator waveGenerator;

	private GlassEdge glassEdge;

	private LiquidIllumination brighterLiquid;

	private LiquidIllumination brightestLiquid;

	private LiquidColorData colorData;

	private int xSize;

	private int ySize = 1;

	private float height;

	private float width = 1.8f;

	private float oneSegmentWidth = 0.18f;

	private Vector3[] vertices;

	private int[] triangles;

	private float[] upperWave;

	private float[] lowerWave;

	private int lowerWaveBufferIndex;

	private int upperWaveBufferIndex;

	private float upperWaveMultiplier;

	private float lowerWaveMultiplier;

	private float targetUpperWaveMultiplier;

	private float targetLowerWaveMultiplier;

	private Mesh mesh;

	private float liquidLimitPosition;

	[HideInInspector]
	public LiquidType type;

	private bool stop;

	private void Awake()
	{
		DefineConnections();
	}

	private void Start()
	{
		InitializeLiquidParameters();
		InitializeArrays();
	}

	private void FixedUpdate()
	{
		GetWavesBuffers();
		GenerateMesh();
		brighterLiquid.SetIlluminationHeight(height + upperWave[Mathf.RoundToInt(xSize / 2)] * upperWaveMultiplier);
		brighterLiquid.SetIlluminationLowerEdgePosition(height, lowerWave[Mathf.RoundToInt(xSize / 2)] * lowerWaveMultiplier);
		brightestLiquid.SetIlluminationHeight(height + upperWave[Mathf.RoundToInt(xSize / 2)] * upperWaveMultiplier * 0.5f);
		brightestLiquid.SetIlluminationLowerEdgePosition(height, lowerWave[Mathf.RoundToInt(xSize / 2)] * lowerWaveMultiplier * 0.5f);
	}

	public void FillUpLiquid(float speed)
	{
		GlassEdge obj = glassEdge;
		Vector3 liquidUpperPosition = GetLiquidUpperPosition();
		float glassWidthAtHeight = obj.GetGlassWidthAtHeight(liquidUpperPosition.y);
		float num = 1f + (3.6f - glassWidthAtHeight) * 0.55f;
		float num2 = num * speed * Time.deltaTime;
		if (!stop && GetLiquidWaveUpperPosition() + num2 <= liquidLimitPosition)
		{
			height += num2;
			waveGenerator.CreateFillingUpWave(speed);
			return;
		}
		stop = true;
		waveGenerator.CreateFillingUpWave(0f);
		waveGenerator.SpeedUpZeroingParameters();
		StartCoroutine(FillUpLiquidToReachGlassEdge());
		Object.FindObjectOfType<GameController>().OnDrinkOverflowed();
	}

	private IEnumerator FillUpLiquidToReachGlassEdge()
	{
		float heightToPour = waveGenerator.GetCurrentAmplitude() * upperWaveMultiplier;
		if (!(heightToPour <= 0f))
		{
			while (heightToPour > 0f)
			{
				float deltaHeight = Time.deltaTime * 4f * upperWaveMultiplier;
				height += deltaHeight;
				heightToPour -= deltaHeight;
				yield return null;
			}
		}
	}

	public void FillUpLiquidPerfectlyToHeight(float targetHeight)
	{
		float num = height;
		Vector3 liquidUpperPosition = GetLiquidUpperPosition();
		height = num + (targetHeight - liquidUpperPosition.y);
	}

	public float GetLiquidWaveUpperPosition()
	{
		Vector3 position = base.transform.position;
		return position.y + height + waveGenerator.GetCurrentAmplitude() * upperWaveMultiplier;
	}

	public Vector3 GetLiquidUpperPosition()
	{
		Vector3 position = base.transform.position;
		position.y += height;
		return position;
	}

	public bool IsLiquidPoured()
	{
		if (height > 0.01f)
		{
			return true;
		}
		return false;
	}

	public void SetNewWaveMultipliers(float newLowerWaveMultiplier, float newUpperWaveMultiplier)
	{
		targetLowerWaveMultiplier = newLowerWaveMultiplier;
		targetUpperWaveMultiplier = newUpperWaveMultiplier;
		StartCoroutine(UpdateLowerWaveMultiplier());
		StartCoroutine(UpdateUpperWaveMultiplier());
	}

	public void SetWaveBufferIndexes(int lowerWaveIndex, int upperWaveIndex)
	{
		lowerWaveBufferIndex = lowerWaveIndex;
		upperWaveBufferIndex = upperWaveIndex;
	}

	public void SetLiquidLimitPosition(float limit)
	{
		liquidLimitPosition = limit;
	}

	private void GenerateMesh()
	{
		int num = 0;
		for (int i = 0; i <= ySize; i++)
		{
			for (int j = 0; j <= xSize; j++)
			{
				vertices[num].x = (0f - width) * 0.5f + (float)j * (width / (float)xSize);
				vertices[num].y = (float)i * (height / (float)ySize);
				if (IsLiquidPoured())
				{
					if (i == 0)
					{
						vertices[num].y += lowerWave[j] * lowerWaveMultiplier;
					}
					else
					{
						vertices[num].y += upperWave[j] * upperWaveMultiplier;
					}
				}
				num++;
			}
		}
		int num2 = 0;
		int num3 = 0;
		int num4 = 0;
		while (num4 < ySize)
		{
			int num5 = 0;
			while (num5 < xSize)
			{
				triangles[num2] = num3;
				triangles[num2 + 3] = (triangles[num2 + 2] = num3 + 1);
				triangles[num2 + 4] = (triangles[num2 + 1] = num3 + xSize + 1);
				triangles[num2 + 5] = num3 + xSize + 2;
				num5++;
				num2 += 6;
				num3++;
			}
			num4++;
			num3++;
		}
		mesh.RecalculateBounds();
		mesh.vertices = vertices;
		mesh.triangles = triangles;
	}

	private void GetWavesBuffers()
	{
		waveGenerator.GetWaveBuffer(ref lowerWave, lowerWaveBufferIndex);
		waveGenerator.GetWaveBuffer(ref upperWave, upperWaveBufferIndex);
	}

	private void InitializeLiquidParameters()
	{
		float glassMaxWidth = glassEdge.GetGlassMaxWidth();
		width = (float)(xSize = Mathf.FloorToInt(glassMaxWidth / oneSegmentWidth) + 1) * oneSegmentWidth;
		LiquidIllumination liquidIllumination = brighterLiquid;
		float liquidWidth = width;
		Vector3 position = base.transform.position;
		liquidIllumination.InitializeIllumination(liquidWidth, position.y);
		LiquidIllumination liquidIllumination2 = brightestLiquid;
		float liquidWidth2 = width;
		Vector3 position2 = base.transform.position;
		liquidIllumination2.InitializeIllumination(liquidWidth2, position2.y);
	}

	private void InitializeArrays()
	{
		vertices = new Vector3[(xSize + 1) * (ySize + 1)];
		triangles = new int[xSize * ySize * 6];
		lowerWave = new float[xSize + 1];
		upperWave = new float[xSize + 1];
	}

	public void SetLiquidTypeAndLiquidMaterial(LiquidType liquidType)
	{
		LiquidColorData colorDataForLiquid = Globals.instance.liquidColorsDataManager.GetColorDataForLiquid(liquidType);
		type = liquidType;
		GetComponent<FizzyBubblesController>().CheckIfLiquidIsFizzy(type);
		Material material = meshRenderer.material;
		Material material2 = new Material(material);
		material2.color = colorDataForLiquid.glassLiquidBase;
		material2.name = LiquidTypes.GetLiquidName(liquidType);
		meshRenderer.material = material2;
		brighterLiquid.SetIlluminationColor(colorDataForLiquid.glassLiquidBrighter);
		brightestLiquid.SetIlluminationColor(colorDataForLiquid.glassLiquidBrightest);
	}

	private void DefineConnections()
	{
		waveGenerator = GetComponentInParent<WaveGenerator>();
		glassEdge = GetComponentInParent<GlassEdge>();
		meshFilter = GetComponent<MeshFilter>();
		meshRenderer = GetComponent<MeshRenderer>();
		mesh = meshFilter.mesh;
		brighterLiquid = base.transform.FindDeepChild("BrighterIllumination").GetComponent<LiquidIllumination>();
		brightestLiquid = base.transform.FindDeepChild("BrightestIllumination").GetComponent<LiquidIllumination>();
	}

	private IEnumerator UpdateLowerWaveMultiplier()
	{
		if (lowerWaveMultiplier < targetLowerWaveMultiplier)
		{
			while (true)
			{
				lowerWaveMultiplier += 0.2f * Time.deltaTime;
				if (lowerWaveMultiplier >= targetLowerWaveMultiplier)
				{
					break;
				}
				yield return null;
			}
			lowerWaveMultiplier = targetLowerWaveMultiplier;
		}
		else
		{
			if (!(lowerWaveMultiplier > targetLowerWaveMultiplier))
			{
				yield break;
			}
			while (true)
			{
				lowerWaveMultiplier -= 0.2f * Time.deltaTime;
				if (lowerWaveMultiplier <= targetLowerWaveMultiplier)
				{
					break;
				}
				yield return null;
			}
			lowerWaveMultiplier = targetLowerWaveMultiplier;
		}
	}

	private IEnumerator UpdateUpperWaveMultiplier()
	{
		if (upperWaveMultiplier < targetUpperWaveMultiplier)
		{
			while (true)
			{
				upperWaveMultiplier += 0.2f * Time.deltaTime;
				if (upperWaveMultiplier >= targetUpperWaveMultiplier)
				{
					break;
				}
				yield return null;
			}
			upperWaveMultiplier = targetUpperWaveMultiplier;
		}
		else
		{
			if (!(upperWaveMultiplier > targetUpperWaveMultiplier))
			{
				yield break;
			}
			while (true)
			{
				upperWaveMultiplier -= 0.2f * Time.deltaTime;
				if (upperWaveMultiplier <= targetUpperWaveMultiplier)
				{
					break;
				}
				yield return null;
			}
			upperWaveMultiplier = targetUpperWaveMultiplier;
		}
	}

	public void ShineOnEndOfPouringLiquid()
	{
		if (colorData == null)
		{
			colorData = Globals.instance.liquidColorsDataManager.GetColorDataForLiquid(type);
		}
		iTween.ValueTo(base.gameObject, iTween.Hash("from", 0f, "to", 1f, "easetype", iTween.EaseType.easeInOutCirc, "onupdate", "ChangeColorsTween", "oncomplete", "ChangeBackColors", "time", 0.25f));
	}

	private void ChangeBackColors()
	{
		iTween.ValueTo(base.gameObject, iTween.Hash("from", 1.0, "to", 0f, "easetype", iTween.EaseType.easeInQuad, "onupdate", "ChangeColorsTween", "time", 0.6f));
	}

	private void ChangeColorsTween(float value)
	{
		meshRenderer.material.color = Color.Lerp(colorData.glassLiquidBase, colorData.glassLiquidBaseShine, value);
		brighterLiquid.SetIlluminationColor(Color.Lerp(colorData.glassLiquidBrighter, colorData.glassLiquidBrighterShine, value));
		brightestLiquid.SetIlluminationColor(Color.Lerp(colorData.glassLiquidBrightest, colorData.glassLiquidBrightestShine, value));
	}

	public float GetRawHeight()
	{
		return height;
	}

	public void SetRawHeight(float height)
	{
		this.height = height;
	}

	public float GetRawWidth()
	{
		return width;
	}

	public LiquidColorData GetColorData()
	{
		if (colorData == null)
		{
			colorData = Globals.instance.liquidColorsDataManager.GetColorDataForLiquid(type);
		}
		return colorData;
	}
}
